package edu.vt.sdm.tcga.filenavigator.parser;

import java.io.File;

import edu.vt.sdm.tcga.filenavigator.parser.clinical.ClinicalAliquotTable;
import edu.vt.sdm.tcga.filenavigator.parser.clinical.ClinicalAnalyteTable;
import edu.vt.sdm.tcga.filenavigator.parser.clinical.ClinicalPortionTable;
import edu.vt.sdm.tcga.filenavigator.parser.clinical.ClinicalProtocolTable;
import edu.vt.sdm.tcga.filenavigator.parser.clinical.ClinicalSampleTable;
import edu.vt.sdm.tcga.filenavigator.parser.clinical.ClinicalSlideTable;
import edu.vt.sdm.tcga.filenavigator.parser.expression.level1.GeneExpressionTable;
import edu.vt.sdm.tcga.filenavigator.parser.expression.level2.LowessNormalizedTable;
import edu.vt.sdm.tcga.filenavigator.parser.expression.level3.AnalysisTable;
import edu.vt.sdm.tcga.filenavigator.parser.methylation.level1.MethylationTable;
import edu.vt.sdm.tcga.filenavigator.parser.methylation.level2.MethylationSignalIntensityTable;
import edu.vt.sdm.tcga.filenavigator.parser.methylation.level3.MethylationAnalysisTable;
import edu.vt.sdm.tcga.filenavigator.parser.snp.level3.SNPAnalysisTable;

public class TCGAFileParser {

	/**
	 * @param args
	 */
	public static void parse(String[] args) {

		// Basically, we need to feed this a base directory, and let it walk the 
		// subdirectories looking for the structures, and loading the various
		// files we find.

		// Make sure we have a directory to traverse...
		if(args.length != 1){
			System.out.println("usage: TCGAParser \"<basedir>\"");
			System.out.println("\t<basedir> is the location of the base genome directory");
			System.exit(1);
		}
		
		// Get current time
		long start = System.currentTimeMillis();
				
		String baseGenomeDir = args[0];

		traverse(new File(baseGenomeDir));

		// Get elapsed time in milliseconds
		long elapsedTimeMillis = System.currentTimeMillis()-start;
		double seconds = elapsedTimeMillis / 1000.0;
		
		System.out.println("Run completed. Total time: " + seconds + " seconds");
	}
	
	
	// Directory traversal routines
    private static void processDirectory(File dir) {

    	
		String filename = dir.getName();
		int level = 0;
		int dataType = 0;
		
		// Figure out which type we're processing. Brute force method.
		int clinical = dir.getAbsolutePath().indexOf("Clinical");
		int methylation = dir.getAbsolutePath().indexOf("DNA_Methylation");
		int expression = dir.getAbsolutePath().indexOf("Expression-Genes");
		int snp = dir.getAbsolutePath().indexOf("SNP");
		
		if(clinical != -1){
			dataType = 10;
		}
		
		if(methylation != -1){
			dataType = 20;
		}
		
		if(expression != -1){
			dataType = 30;
		}
		
		if(snp != -1){
			dataType = 40;
		}
		
		
    	// Figure out which Level we're processing
		int index = dir.getAbsolutePath().indexOf("Level_");
		
		if(index != -1){
			String levelStr = dir.getAbsolutePath().substring(index + 6, index + 7);
			level = Integer.parseInt(levelStr);
		}
		else{
			// Clinical?
			if(dataType == 10){
				
				if(dir.getName().contains("aliquot")){
					level = 1;
				}
				if(dir.getName().contains("analyte")){
					level = 2;
				}
				if(dir.getName().contains("portion")){
					level = 3;
				}
				if(dir.getName().contains("protocol")){
					level = 4;
				}
				if(dir.getName().contains("sample")){
					level = 5;
				}
				if(dir.getName().contains("slide")){
					level = 6;
				}
			}
		}

		level += dataType;
		
    	// Process the file.
		if(dir.isDirectory() == false){
			
			switch(level){
			// Clinical
			case 11:
		        System.out.println("Processing Clinical Aliquot file: " + filename);
		        processClinicalAliquotFile(dir.getAbsolutePath());
				break;
			case 12:
		        System.out.println("Processing Clinical Analyte file: " + filename);
		        processClinicalAnalyteFile(dir.getAbsolutePath());
				break;
			case 13:
		        System.out.println("Processing Clinical Portion file: " + filename);
		        processClinicalPortionFile(dir.getAbsolutePath());
				break;
			case 14:
		        System.out.println("Processing Clinical Protocol file: " + filename);
		        processClinicalProtocolFile(dir.getAbsolutePath());
				break;
			case 15:
		        System.out.println("Processing Clinical Sample file: " + filename);
		        processClinicalSampleFile(dir.getAbsolutePath());
				break;
			case 16:
		        System.out.println("Processing Clinical Slide file: " + filename);
		        processClinicalSlideFile(dir.getAbsolutePath());
				break;
			//Methylation
			case 21:
		        System.out.println("Processing Methylation Level 1 file: " + filename);
		        processMethylationLevel1File(dir.getAbsolutePath());
				break;
			case 22:
		        System.out.println("Processing Methylation Level 2 file: " + filename);
		        processMethylationLevel2File(dir.getAbsolutePath());
				break;
			case 23:
		        System.out.println("Processing Methylation Level 3 file: " + filename);
		        processMethylationLevel3File(dir.getAbsolutePath());
				break;
			// Gene Expression
			case 31:
		        System.out.println("Processing Gene Expression Level 1 file: " + filename);
		        processExpressionLevel1File(dir.getAbsolutePath());
				break;
			case 32:
		        System.out.println("Processing Gene Expression Level 2 file: " + filename);
		        processExpressionLevel2File(dir.getAbsolutePath());
				break;
			case 33:
		        System.out.println("Processing Gene Expression Level 3 file: " + filename);
		        processExpressionLevel3File(dir.getAbsolutePath());
				break;
			// SNP
			case 41:
		        System.out.println("Processing SNP Level 1 file: " + filename);
		        processSNPLevel1File(dir.getAbsolutePath());
				break;
			case 42:
		        System.out.println("Processing SNP Level 2 file: " + filename);
		        processSNPLevel2File(dir.getAbsolutePath());
				break;
			case 43:
		        System.out.println("Processing SNP Level 3 file: " + filename);
		        processSNPLevel3File(dir.getAbsolutePath());
				break;

			default:
				break;
			}
    	}
    	
        System.gc();
    }

    private static void traverse(File dir) {

    	processDirectory(dir);

        if (dir.isDirectory()) {
            
        	String[] children = dir.list();
            
            for (int i=0; i<children.length; i++) {
                traverse(new File(dir, children[i]));
            }
        }
    }

    // Clinical
    private static void processClinicalAliquotFile(String filename){
        
		ClinicalAliquotTable cTable = new ClinicalAliquotTable(filename);
		cTable.saveToDatabase();

		System.gc();
    }
    
    private static void processClinicalAnalyteFile(String filename){
        
		ClinicalAnalyteTable cTable = new ClinicalAnalyteTable(filename);
		cTable.saveToDatabase();

		System.gc();
    }
    
    private static void processClinicalPortionFile(String filename){
        
		ClinicalPortionTable cTable = new ClinicalPortionTable(filename);
		cTable.saveToDatabase();

		System.gc();
    }
    
    private static void processClinicalProtocolFile(String filename){
        
		ClinicalProtocolTable cTable = new ClinicalProtocolTable(filename);
		cTable.saveToDatabase();

		System.gc();
    }
    
    private static void processClinicalSampleFile(String filename){
        
		ClinicalSampleTable cTable = new ClinicalSampleTable(filename);
		cTable.saveToDatabase();

		System.gc();
    }
    
    private static void processClinicalSlideFile(String filename){
        
		ClinicalSlideTable cTable = new ClinicalSlideTable(filename);
		cTable.saveToDatabase();

		System.gc();
    }
    
    // Methylation
    private static void processMethylationLevel1File(String filename){
        
		MethylationTable mTable = new MethylationTable(filename);
		mTable.saveToDatabase();

		System.gc();
    }

    private static void processMethylationLevel2File(String filename){
        
		MethylationSignalIntensityTable mTable = new MethylationSignalIntensityTable(filename);
		mTable.saveToDatabase();

		System.gc();
    }

    private static void processMethylationLevel3File(String filename){
        
		MethylationAnalysisTable mTable = new MethylationAnalysisTable(filename);
		mTable.saveToDatabase();

		System.gc();
    }

   
    // Gene Expression
    private static void processExpressionLevel1File(String filename){
        
		GeneExpressionTable geTable = new GeneExpressionTable(filename);
		geTable.saveToDatabase();

		System.gc();
    }

    private static void processExpressionLevel2File(String filename){
        
		LowessNormalizedTable lnTable = new LowessNormalizedTable(filename);
		lnTable.saveToDatabase();

		System.gc();
    }

    private static void processExpressionLevel3File(String filename){
    	
		AnalysisTable aTable = new AnalysisTable(filename);
		aTable.saveToDatabase();
    	System.gc();
    }
    
    // SNP
    private static void processSNPLevel1File(String filename){
        
//		GeneExpressionTable geTable = new GeneExpressionTable(filename);
//		geTable.saveToDatabase();

		System.gc();
    }
  
    private static void processSNPLevel2File(String filename){
        
//		GeneExpressionTable geTable = new GeneExpressionTable(filename);
//		geTable.saveToDatabase();

		System.gc();
    }
  
    private static void processSNPLevel3File(String filename){
        
		SNPAnalysisTable geTable = new SNPAnalysisTable(filename);
		geTable.saveToDatabase();

		System.gc();
    }
}
